package com.crane.common.web.controller;

import com.crane.common.core.dto.MultiResponse;
import com.crane.common.core.dto.SingleResponse;
import com.crane.common.core.exception.AppException;
import com.crane.common.core.exception.BasicErrorCode;
import com.crane.common.core.exception.BizException;
import com.crane.oss.common.bean.resp.AliyunOSSBean;
import com.crane.oss.common.service.AliyunOSSService;
import com.crane.oss.web.BaseBusinessController;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.imageio.ImageIO;
import javax.validation.Valid;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;

/**
 * 文件上传-阿里云OSS
 *
 * @author tyh
 */
@Api(value = "FileController", tags = {"文件上传接口"})
@RestController
@RequestMapping("/api/file")
public class FileController extends BaseBusinessController {

    private static final Logger logger = LoggerFactory.getLogger(FileController.class);

    @Autowired
    private AliyunOSSService aliyunOSSService;

    @ApiOperation(value = "通用上传", notes = "包括文件、图片、视频")
    @RequestMapping(value = "/common", method = {RequestMethod.POST}, produces = "application/json;charset=UTF-8")
    @ResponseBody
    public SingleResponse<AliyunOSSBean> common(@RequestParam("file") @Valid MultipartFile upFile) {
    	long s1 = System.currentTimeMillis();
    	String[] allowedType = {"application/msword", "application/pdf", "application/vnd.ms-powerpoint","text/plain","application/vnd.ms-excel",
    			"application/vnd.openxmlformats-officedocument.wordprocessingml.document","application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
    			"video/mp4", "audio/mpeg", "video/mpeg","audio/mp4","video/mpeg",
    			"image/bmp", "image/gif", "image/jpeg", "image/png","image/jpg"};
    	String[] fileAllowedType = {"application/msword", "application/pdf", "application/vnd.ms-powerpoint","text/plain","application/vnd.ms-excel",
    			"application/vnd.openxmlformats-officedocument.wordprocessingml.document","application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"};
    	String[] videoAllowedType = {"video/mp4", "audio/mpeg", "video/mpeg","audio/mp4","video/mpeg"};
    	String[] imageAllowedType = {"image/bmp", "image/gif", "image/jpeg", "image/png","image/jpg"};

    	if (!Arrays.asList(allowedType).contains(upFile.getContentType())) {
    		throw new AppException(BasicErrorCode.FILE_FORMAT);
    	}

    	boolean fileFlag = false;
    	boolean videoFlag =  false;
    	boolean imageFlag =  false;
    	if (Arrays.asList(fileAllowedType).contains(upFile.getContentType())) {
            if (upFile.getSize() > 10 * 1024 * 1024) {
            	throw new AppException(BasicErrorCode.FILE_SIZE);
            } else {
            	fileFlag = true;
            }
    	}
    	if (Arrays.asList(videoAllowedType).contains(upFile.getContentType())) {
            if (upFile.getSize() > 20 * 1024 * 1024) {
            	throw new AppException(BasicErrorCode.VIDEO_SIZE);
            } else {
            	videoFlag = true;
            }
    	}
    	if (Arrays.asList(imageAllowedType).contains(upFile.getContentType())) {
            if (upFile.getSize() > 4 * 1024 * 1024) {
            	throw new AppException(BasicErrorCode.IMAGE_SIZE);
            } else {
            	imageFlag = true;
            }
    	}

        // 包含原始文件名的字符串
        String fileName = upFile.getOriginalFilename();
        // 提取文件拓展名
        String prefix = fileName.substring(fileName.indexOf("."), fileName.length());
        // 生成云端的真实文件名
        String remoteFileName = UUID.randomUUID().toString() + prefix;

        String url = null;
        AliyunOSSBean response = new AliyunOSSBean();
        try {
        	File file = null;
        	if (!imageFlag) {
            	file = File.createTempFile(fileName, prefix);
            	upFile.transferTo(file);
        	}

            if (fileFlag) {
            	url = aliyunOSSService.uploadFile(file, remoteFileName);
            }
            if (videoFlag) {
            	url = aliyunOSSService.uploadVideo(file, remoteFileName);
            }
            if (imageFlag) {
                BufferedImage bi = ImageIO.read(upFile.getInputStream());
                int width = bi.getWidth();
                int height = bi.getHeight();

            	url = aliyunOSSService.uploadImage(upFile.getBytes(), remoteFileName);
                response.setHeight(height);
                response.setWidth(width);
            }

            response.setUrl(url);
            response.setAttachName(fileName);
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            throw new BizException();
        }

        long s2 = System.currentTimeMillis();
        logger.info("单个上传文件common用时：{}ms,url={}", s2 - s1, url);
        return SingleResponse.of(response);
    }

    @ApiOperation(value = "上传文件", notes = "上传文件：doc pdf ppt txt xls docx xlsx")
    @RequestMapping(value = "/file", method = {RequestMethod.POST}, produces = "application/json;charset=UTF-8")
    @ResponseBody
    public SingleResponse<AliyunOSSBean> file(@RequestParam("file") @Valid MultipartFile upFile) {
        long s1 = System.currentTimeMillis();
        // 文件类型限制doc pdf ppt txt xls docx xlsx
        String[] allowedType = {"application/msword", "application/pdf", "application/vnd.ms-powerpoint","text/plain","application/vnd.ms-excel",
        		"application/vnd.openxmlformats-officedocument.wordprocessingml.document","application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"};
        boolean allowed = Arrays.asList(allowedType).contains(upFile.getContentType());
        if (!allowed) {
        	throw new AppException(BasicErrorCode.FILE_FORMAT);
        }
        // 文件大小限制
        if (upFile.getSize() > 10 * 1024 * 1024) {
        	throw new AppException(BasicErrorCode.FILE_SIZE);
        }
        // 包含原始文件名的字符串
        String fileName = upFile.getOriginalFilename();
        // 提取文件拓展名
        String prefix = fileName.substring(fileName.indexOf("."), fileName.length());
        // 生成云端的真实文件名
        String remoteFileName = UUID.randomUUID().toString() + prefix;

        String url = null;

        AliyunOSSBean response = new AliyunOSSBean();
        try {
        	File file = File.createTempFile(fileName, prefix);
        	upFile.transferTo(file);

            url = aliyunOSSService.uploadFile(file, remoteFileName);

            response.setUrl(url);
            response.setAttachName(fileName);
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            throw new BizException();
        }

        long s2 = System.currentTimeMillis();
        logger.info("单个上传文件file用时：{}ms,url={}", s2 - s1, url);
        return SingleResponse.of(response);
    }

    @ApiOperation(value = "上传视频", notes = "上传视频：mp4 mp3 mpg mpeg")
    @RequestMapping(value = "/video", method = {RequestMethod.POST}, produces = "application/json;charset=UTF-8")
    @ResponseBody
    public SingleResponse<AliyunOSSBean> video(@RequestParam("file") @Valid MultipartFile upFile) {
        long s1 = System.currentTimeMillis();
        // 文件类型限制mp4 mp3 mpg mpeg
        String[] allowedType = {"video/mp4", "audio/mpeg", "video/mpeg","audio/mp4","video/mpeg"};
        boolean allowed = Arrays.asList(allowedType).contains(upFile.getContentType());
        if (!allowed) {
        	throw new AppException(BasicErrorCode.VIDEO_FORMAT);
        }
        // 视频大小限制
        if (upFile.getSize() > 20 * 1024 * 1024) {
        	throw new AppException(BasicErrorCode.VIDEO_SIZE);
        }
        // 包含原始文件名的字符串
        String fileName = upFile.getOriginalFilename();
        // 提取文件拓展名
        String prefix = fileName.substring(fileName.indexOf("."), fileName.length());
        // 生成云端的真实文件名
        String remoteFileName = UUID.randomUUID().toString() + prefix;

        String url = null;
        AliyunOSSBean response = new AliyunOSSBean();
        try {
        	File file = File.createTempFile(fileName, prefix);
        	upFile.transferTo(file);

            url = aliyunOSSService.uploadVideo(file, remoteFileName);

            response.setUrl(url);
            response.setAttachName(fileName);
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            throw new BizException();
        }

        long s2 = System.currentTimeMillis();
        logger.info("单个上传文件video用时：{}ms,url={}", s2 - s1, url);
        return SingleResponse.of(response);
    }

    @ApiOperation(value = "上传图片", notes = "上传图片：bmp gif jpeg png jpg")
    @RequestMapping(value = "/image", method = {RequestMethod.POST}, produces = "application/json;charset=UTF-8")
    @ResponseBody
    public SingleResponse<AliyunOSSBean> upload(@RequestParam("file") @Valid MultipartFile upFile) throws BizException {
        long s1 = System.currentTimeMillis();
        // 文件类型限制bmp gif jpeg png jpg
        String[] allowedType = {"image/bmp", "image/gif", "image/jpeg", "image/png","image/jpg"};
        boolean allowed = Arrays.asList(allowedType).contains(upFile.getContentType());
        if (!allowed) {
        	throw new AppException(BasicErrorCode.IMAGE_FORMAT);
        }
        // 图片大小限制
        if (upFile.getSize() > 4 * 1024 * 1024) {
        	throw new AppException(BasicErrorCode.IMAGE_SIZE);
        }

        // 包含原始文件名的字符串
        String fi = upFile.getOriginalFilename();
        // 提取文件拓展名
        String fileNameExtension = fi.substring(fi.indexOf("."), fi.length());
        // 生成云端的真实文件名
        String remoteFileName = UUID.randomUUID().toString() + fileNameExtension;

        String url = null;
        AliyunOSSBean response = new AliyunOSSBean();
        try {
            BufferedImage bi = ImageIO.read(upFile.getInputStream());
            int width = bi.getWidth();
            int height = bi.getHeight();

            url = aliyunOSSService.uploadImage(upFile.getBytes(), remoteFileName);

            response.setHeight(height);
            response.setWidth(width);
            response.setUrl(url);
            response.setCoverUrl(url);
            response.setAttachName(fi);
        } catch (IOException e) {
            logger.error(e.getMessage(), e);
            throw new BizException();
        }

        long s2 = System.currentTimeMillis();
        logger.info("单个上传文件image用时：{}ms,url={}", s2 - s1, url);
        return SingleResponse.of(response);
    }

    @ApiOperation(value = "批量上传图片", notes = "批量上传图片：bmp gif jpeg png jpg")
    @RequestMapping(value = "/images", method = {RequestMethod.POST}, produces = "application/json;charset=UTF-8")
    @ResponseBody
    public MultiResponse<AliyunOSSBean> upload(@RequestParam("files") MultipartFile[] files) throws BizException {
        long s1 = System.currentTimeMillis();
        List<AliyunOSSBean> responseList = new ArrayList<AliyunOSSBean>();
        if (files != null && files.length > 0) {
            for (int i = 0; i < files.length; i++) {
                MultipartFile file = files[i];
                // 文件类型限制
                String[] allowedType = {"image/bmp", "image/gif", "image/jpeg", "image/png","image/jpg"};
                boolean allowed = Arrays.asList(allowedType).contains(file.getContentType());
                if (!allowed) {
                	throw new AppException(BasicErrorCode.IMAGE_FORMAT);
                }
                // 图片大小限制
                if (file.getSize() > 4 * 1024 * 1024) {
                	throw new AppException(BasicErrorCode.IMAGE_SIZE);
                }
                // 包含原始文件名的字符串
                String fi = file.getOriginalFilename();
                // 提取文件拓展名
    	        String fileNameExtension = fi.substring(fi.indexOf("."), fi.length());
                // 生成云端的真实文件名
    	        String remoteFileName = UUID.randomUUID().toString() + fileNameExtension;

                AliyunOSSBean response = new AliyunOSSBean();
                try {
                    BufferedImage bi = ImageIO.read(file.getInputStream());
                    int width = bi.getWidth();
                    int height = bi.getHeight();

                    String url = aliyunOSSService.uploadImage(file.getBytes(), remoteFileName);

                    response.setHeight(height);
                    response.setWidth(width);
                    response.setUrl(url);
                    response.setCoverUrl(url);
                    response.setAttachName(fi);
                } catch (IOException e) {
                    logger.error(e.getMessage(), e);
                    throw new BizException();
                }
                responseList.add(response);
            }
        }

        long s2 = System.currentTimeMillis();
        logger.info("批量上传图片Controller用时：:{}ms", s2 - s1);
        return MultiResponse.of(responseList, responseList.size());
    }

    @SuppressWarnings("rawtypes")
	@ApiOperation(value = "删除文件", notes = "删除文件")
    @PostMapping("/delete")
    public SingleResponse deleteFile(@RequestBody @Valid String[] urlList) {
    	if (urlList != null && urlList.length > 0) {
    		for (int i = 0; i < urlList.length; i++) {
    			String url = urlList[i];
    			int index = url.lastIndexOf("/");
    			String remoteFileName = url.substring(index + 1);

    			String filePath = "";
    			if (url.contains("file")) {
                    filePath="file/";
                }
    			if (url.contains("image")) {
                    filePath="image/";
                }
    			if (url.contains("video")) {
                    filePath="video/";
                }
    	        aliyunOSSService.deleteFile(remoteFileName, filePath);
    	        logger.info("FileController deleteFile: " + url);
    		}
    	}

        return SingleResponse.buildSuccess();
    }

}
